package cranim.graphics;

import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;

import javax.imageio.ImageIO;
import org.imgscalr.Scalr;

public class SpriteStore {
    
	private static SpriteStore store = new SpriteStore();
	
	public static SpriteStore get() {
		return store;
	}
	
	private HashMap sprites = new HashMap();
	
	public Sprite getSprite(String ref, boolean force, double scale, double rotation) {
		if (sprites.get(ref) != null && !force) {
			return (Sprite) sprites.get(ref);
		}
		
		BufferedImage sourceImage = null;
		
		try {
			URL url = this.getClass().getClassLoader().getResource(ref);
			
			if (url == null) {
				error("Can't find ref: "+ref);
			}
			
			sourceImage = ImageIO.read(url);
		} catch (IOException e) {
			error("Failed to load: "+ref);
		}
		
		GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();

                int scaledWidth = (int)(sourceImage.getWidth()*scale);
                int scaledHeight = (int)(sourceImage.getHeight()*scale);

                /*BufferedImage resImage = new BufferedImage(scaledWidth, scaledHeight, Transparency.TRANSLUCENT);
                AffineTransform at = AffineTransform.getScaleInstance(scale, scale);
                g.drawRenderedImage(sourceImage, at);
                g.dispose();*/
                
                BufferedImage resImage = Scalr.resize(sourceImage, Scalr.Method.ULTRA_QUALITY, Scalr.Mode.FIT_TO_WIDTH, scaledWidth, scaledHeight);
                
                Graphics2D g = resImage.createGraphics();
                
                if(rotation != 0){
                    BufferedImage rotImage = new BufferedImage(scaledWidth, scaledWidth, Transparency.TRANSLUCENT);
                    g = rotImage.createGraphics();
                    RenderingHints scalingHints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                    scalingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
                    scalingHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                    scalingHints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
                    scalingHints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
                    scalingHints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                    g.setRenderingHints(scalingHints);
                    AffineTransform at = new AffineTransform(); 
                    at.translate(scaledWidth/2, scaledHeight/2);
                    at.rotate(Math.toRadians(rotation));
                    at.translate(-scaledWidth/2, -scaledHeight/2);                
                    g.drawRenderedImage(resImage, at);
                    g.dispose();
                    Sprite sprite = new Sprite(rotImage); 
                    sprites.put(ref,sprite);
                    return sprite;
                }
                else{
                    Sprite sprite = new Sprite(resImage);
                    sprites.put(ref,sprite);
                    return sprite;
                }
		
	}
	
	private void error(String message) {
		System.out.println(message);
	}
}